<cfcomponent displayname="KalendarDAO" hint="This CFC is intended to populate a calendar with event data. There are specific fields it requires to properly display the recordset!">


	<cfset variables.private = structNew() />

	<cffunction name="init" access="public" output="false" returntype="KalendarDAO">
		<cfargument name="KalendarConfig" type="any" required="true" hint="This is a reference to the main Kalendar Config component"/>
		<cfset variables.private.Config = arguments.KalendarConfig />
		<cfreturn this>
	</cffunction>
	
	<cffunction name="create" access="public" output="false" returntype="boolean">
		<cfargument name="Kalendar" type="any" required="true" />

		<cfset var qCreate = "" />
	<!--- 	<cftry> --->
			<cfquery name="qCreate" datasource="#getConfig().getDSN()#">
				INSERT INTO tblKalendar
					(
					EventID,
					CategoryID,
					IsDeleted,
					IsPublished,
					IsFeatured,
					DateTimeCreated,
					StartDate,
					EndDate,
					<cfif len( trim( arguments.Kalendar.getStartTime() ) )>
						StartTime,
					</cfif>
					<cfif len( trim( arguments.Kalendar.getEndTime() ) )>
						EndTime,
					</cfif>
					ContactPhone,
					ContactName,
					ContactEmail,
					Title,
					Location,
					Teaser,
					ExternalURL,
					Description
					)
				VALUES
					(
					<cfqueryparam value="#CreateUUID()#" CFSQLType="cf_sql_varchar" />,
					<cfqueryparam value="#arguments.Kalendar.getCategoryID()#" CFSQLType="cf_sql_integer" />,
					<cfqueryparam value="#yesNoFormat(arguments.Kalendar.getIsDeleted())#" CFSQLType="cf_sql_bit" />,
					<cfqueryparam value="#yesNoFormat(arguments.Kalendar.getIsPublished())#" CFSQLType="cf_sql_bit" />,
					<cfqueryparam value="#yesNoFormat(arguments.Kalendar.getIsFeatured())#" CFSQLType="cf_sql_bit" />,
					<cfqueryparam value="#CreateODBCDate(now())#" CFSQLType="cf_sql_date" />,
					<cfqueryparam value="#CreateODBCDate(arguments.Kalendar.getStartDate())#" CFSQLType="cf_sql_date" />,
					<cfqueryparam value="#CreateODBCDate(arguments.Kalendar.getEndDate())#" CFSQLType="cf_sql_date" />,
					<cfif len( trim( arguments.Kalendar.getStartTime() ) )>
						<cfqueryparam value="#CreateODBCTime(arguments.Kalendar.getStartTime())#" cfsqltype="cf_sql_varchar" />, 
					</cfif>
					<cfif len( trim( arguments.Kalendar.getEndTime() ) )>
						<cfqueryparam value="#CreateODBCTime(arguments.Kalendar.getEndTime())#" cfsqltype="cf_sql_varchar" />, 
					</cfif>				
					<cfqueryparam value="#arguments.Kalendar.getContactPhone()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getContactPhone())#" />,
					<cfqueryparam value="#arguments.Kalendar.getContactName()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getContactName())#" />,
					<cfqueryparam value="#arguments.Kalendar.getContactEmail()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getContactEmail())#" />,
					<cfqueryparam value="#arguments.Kalendar.getTitle()#" CFSQLType="cf_sql_varchar" />,
					<cfqueryparam value="#arguments.Kalendar.getLocation()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getLocation())#" />,
					<cfqueryparam value="#arguments.Kalendar.getTeaser()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getTeaser())#" />,
					<cfqueryparam value="#arguments.Kalendar.getExternalURL()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getExternalURL())#" />,
					<cfqueryparam value="#arguments.Kalendar.getDescription()#" CFSQLType="cf_sql_longvarchar" />
					)
			</cfquery>
<!--- 			<cfcatch type="database">
				<cfreturn false />
			</cfcatch>
		</cftry> --->
		<cfreturn true />
	</cffunction>

	<cffunction name="read" access="public" output="false" returntype="void">
		<cfargument name="Kalendar" type="any" required="true" />

		<cfset var qRead = "" />
		<cfset var strReturn = structNew() />
<!--- 		<cftry> --->
			<cfquery name="qRead" datasource="#getConfig().getDSN()#">
				SELECT
					EventID,
					CategoryID,
					IsDeleted,
					IsPublished,
					IsFeatured,
					DateTimeCreated,
					StartDate,
					EndDate,
					StartTime,
					EndTime,
					ContactPhone,
					ContactName,
					ContactEmail,
					Title,
					Location,
					Teaser,
					ExternalURL,
					Description
				FROM	tblKalendar
				WHERE	EventID = <cfqueryparam value="#arguments.Kalendar.getEventID()#" CFSQLType="cf_sql_varchar" />
			</cfquery>
<!--- 			<cfcatch type="database">
				<!--- leave the bean as is and set an empty query for the conditional logic below --->
				<cfset qRead = queryNew("id") />
			</cfcatch>
		</cftry> --->
		<cfif qRead.recordCount>
			<cfset strReturn = queryRowToStruct(qRead)>
			<cfset arguments.Kalendar.init(argumentCollection=strReturn)>
		</cfif>
	</cffunction>

	<cffunction name="update" access="public" output="false" returntype="boolean">
		<cfargument name="Kalendar" type="any" required="true" />

		<cfset var qUpdate = "" />
	<!--- 	<cftry> --->
			<cfquery name="qUpdate" datasource="#getConfig().getDSN()#">
				UPDATE	tblKalendar
				SET
					CategoryID = <cfqueryparam value="#arguments.Kalendar.getCategoryID()#" CFSQLType="cf_sql_integer" />,
					IsDeleted = <cfqueryparam value="#YesNoFormat(arguments.Kalendar.getIsDeleted())#" CFSQLType="cf_sql_bit" />,
					IsPublished = <cfqueryparam value="#YesNoFormat(arguments.Kalendar.getIsPublished())#" CFSQLType="cf_sql_bit" />,
					IsFeatured = <cfqueryparam value="#YesNoFormat(arguments.Kalendar.getIsFeatured())#" CFSQLType="cf_sql_bit"  />,
					StartDate = <cfqueryparam value="#CreateODBCDate(arguments.Kalendar.getStartDate())#" CFSQLType="cf_sql_date" />,
					EndDate = <cfqueryparam value="#CreateODBCDate(arguments.Kalendar.getEndDate())#" CFSQLType="cf_sql_date" />,
					<cfif len( trim( arguments.Kalendar.getStartTime() ) )>
						StartTime = <cfqueryparam value="#CreateODBCTime(arguments.Kalendar.getStartTime())#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getStartTime())#" />,
					</cfif>
					<cfif len( trim( arguments.Kalendar.getEndTime() ) )>
						EndTime = <cfqueryparam value="#CreateODBCTime(arguments.Kalendar.getEndTime())#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getEndTime())#" />,
					</cfif>
					ContactPhone = <cfqueryparam value="#arguments.Kalendar.getContactPhone()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getContactPhone())#" />,
					ContactName = <cfqueryparam value="#arguments.Kalendar.getContactName()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getContactName())#" />,
					ContactEmail = <cfqueryparam value="#arguments.Kalendar.getContactEmail()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getContactEmail())#" />,
					Title = <cfqueryparam value="#arguments.Kalendar.getTitle()#" CFSQLType="cf_sql_varchar" />,
					Location = <cfqueryparam value="#arguments.Kalendar.getLocation()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getLocation())#" />,
					Teaser = <cfqueryparam value="#arguments.Kalendar.getTeaser()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getTeaser())#" />,
					ExternalURL = <cfqueryparam value="#arguments.Kalendar.getExternalURL()#" CFSQLType="cf_sql_varchar" null="#not len(arguments.Kalendar.getExternalURL())#" />,
					Description = <cfqueryparam value="#arguments.Kalendar.getDescription()#" CFSQLType="cf_sql_longvarchar" />
				WHERE	EventID = <cfqueryparam value="#arguments.Kalendar.getEventID()#" CFSQLType="cf_sql_varchar" />
			</cfquery>
<!--- 			<cfcatch type="database">
				<cfreturn false />
			</cfcatch>
		</cftry> --->
		<cfreturn true />
	</cffunction>

	<cffunction name="delete" access="public" output="false" returntype="boolean">
		<cfargument name="Kalendar" type="any" required="true" />

		<cfset var qDelete = "">
		<cftry>
			<cfquery name="qDelete" datasource="#getConfig().getDSN()#">
						
			UPDATE
				tblKalendar
			SET
				IsDeleted = 1
			WHERE
				EventID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.Kalendar.getEventID()#" />
			</cfquery>
			<cfcatch type="database">
				<cfreturn false />
			</cfcatch>
		</cftry>
		<cfreturn true />
	</cffunction>

	<cffunction name="exists" access="public" output="false" returntype="boolean">
		<cfargument name="Kalendar" type="any" required="true" />

		<cfset var qExists = "">
		<cfquery name="qExists" datasource="#getConfig().getDSN()#" maxrows="1">
			SELECT count(1) as idexists
			FROM	tblKalendar
			WHERE	EventID = <cfqueryparam value="#arguments.Kalendar.getEventID()#" CFSQLType="cf_sql_varchar" />
		</cfquery>

		<cfif qExists.idexists>
			<cfreturn true />
		<cfelse>
			<cfreturn false />
		</cfif>
	</cffunction>

	<cffunction name="save" access="public" output="false" returntype="boolean">
		<cfargument name="Kalendar" type="any" required="true" />
		
		<cfset var success = false />
		<cfif exists(arguments.Kalendar)>
			<cfset success = update(arguments.Kalendar) />
		<cfelse>
			<cfset success = create(arguments.Kalendar) />
		</cfif>
		
		<cfreturn success />
	</cffunction>

	<!--- get calendar --->
	<cffunction access="public" 
		name="getCalendar" 
		output="false" 
		returntype="array" 
		displayname="getCalendar" 
		hint="gets data for calendar and converts to a 2d double nested array">
			
		<cfargument name="view" 
				type="string" 
				required="true"
				hint="sets the calendar to display week or month view" />
				
		<cfargument name="StartPeriod" 
				type="date" 
				required="yes"
				hint="begining of this interval." />
				
		<cfargument name="EndPeriod" 
				type="date" 
				required="yes"
				hint="end of this interval." />
				
		<cfargument name="PublicOnly" 
				type="boolean" 
				required="yes"
				hint="Specifies to display events marked only for public consumption." />
				
		<cfargument name="CategoryID" 
				type="numeric" 
				required="yes"
				hint="allows querying of records by category." />
		
		<cfscript>
			var CalendarEvents = ArrayNew(1);
			var ArrayCount = 0;
			

		</cfscript>

		<!--- query for events --->
		<cfquery name="getCalendar" datasource="#getConfig().getDSN()#">

			SELECT
				tblKalendar.*,
				tblKalendarCategories.CategoryName,
				tblKalendarCategories.CategoryBGColor,
				tblKalendarCategories.CategoryTextColor
			FROM
				tblKalendarCategories RIGHT OUTER JOIN
					tblKalendar ON tblKalendarCategories.CategoryID = tblKalendar.CategoryID
			WHERE
				IsDeleted = 0
			<cfswitch expression="#arguments.view#">
				<cfcase value="day">
			AND
				(
					StartDate <= <cfqueryparam cfsqltype="cf_sql_date" value="#arguments.StartPeriod#" />
				AND
					EndDate >= <cfqueryparam cfsqltype="cf_sql_date" value="#arguments.EndPeriod#" />
				)
				</cfcase>
				<cfdefaultcase>
			AND
				(
					(
						StartDate >= <cfqueryparam cfsqltype="cf_sql_date" value="#arguments.StartPeriod#" />
					OR
				  		EndDate >= <cfqueryparam cfsqltype="cf_sql_date" value="#arguments.StartPeriod#" />
				  	)
			AND
					(
						StartDate <= <cfqueryparam cfsqltype="cf_sql_date" value="#arguments.EndPeriod#" />
					OR
						EndDate <= <cfqueryparam cfsqltype="cf_sql_date" value="#arguments.EndPeriod#" />
					)
				)

				</cfdefaultcase>
			</cfswitch>
			<cfif arguments.PublicOnly>
			AND
				IsPublished = 1
			</cfif>
			<cfif arguments.CategoryID neq 0>
			AND
				tblKalendarCategories.CategoryID = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.CategoryID#" />
			</cfif>
			ORDER BY 
				StartDate,
				StartTime,
				EndDate,
				EndTime

		</cfquery> 

		<!--- convert query to array --->
		
		<cfoutput query="getCalendar" group="EventID">
			<cfscript>
				ArrayCount = ArrayCount + 1;
				CalendarEvents[ArrayCount] = StructNew();
			</cfscript>
			<cfoutput>
				<cfscript>
					CalendarEvents[ArrayCount].StartDate = StartDate;
					CalendarEvents[ArrayCount].EndDate = EndDate;
					CalendarEvents[ArrayCount].EndTime = EndTime;
					CalendarEvents[ArrayCount].EventIDLabel = "EventID";
					CalendarEvents[ArrayCount].EventID = EventID;
					CalendarEvents[ArrayCount].Title = Trim(Title);
					CalendarEvents[ArrayCount].Teaser = Trim(Teaser);
					CalendarEvents[ArrayCount].Description = Trim(Description);
					CalendarEvents[ArrayCount].Location = Trim(Location);
					CalendarEvents[ArrayCount].ExternalURL = Trim(ExternalURL);
					CalendarEvents[ArrayCount].CategoryName = CategoryName;
					CalendarEvents[ArrayCount].ContactName = ContactName;
					CalendarEvents[ArrayCount].ContactPhone = ContactPhone;
					CalendarEvents[ArrayCount].ContactEmail = ContactEmail;
					CalendarEvents[ArrayCount].StartTime = StartTime;
					CalendarEvents[ArrayCount].CategoryBGColor = CategoryBGColor;
					CalendarEvents[ArrayCount].CategoryTextColor = CategoryTextColor;
				</cfscript>
			</cfoutput>
		</cfoutput>
		
		<cfreturn CalendarEvents /> 

	</cffunction>
	
	
	<!--- Function KalendarXML --->
	<cffunction access="public" 
			name="loadKalendarXML" 
			output="false" 
			returntype="xml" 
			displayname="KalendarXML" 
			hint="Creates XML from resultset of getCalendar">
			
		<cfargument name="view" 
				type="string" 
				required="true"
				hint="sets the calendar to display week or month view" />
				
		<cfargument name="LinkDate" 
				type="date" 
				required="yes"
				hint="Currently Selected Date." />
								
		<cfargument name="StartPeriod" 
				type="date" 
				required="yes"
				hint="begining of this interval." />
				
		<cfargument name="EndPeriod" 
				type="date" 
				required="yes"
				hint="end of this interval." />
							
		<cfargument name="CategoryID" 
				type="numeric" 
				required="yes"
				hint="allows querying of records by category." />
				
		<cfscript>
			var publishDate = DateConvert("local2Utc", Now());
			var eventdate = "";
			var description = "";
			var category = "";
			var eventid = "";
			var rssFeed = "";
			var KalendarData = "";
			var title = "";
			
			publishDate = DateFormat(publishDate, "ddd, dd mmm yyyy") & " " & TimeFormat(publishDate, "HH:mm:ss") & " GMT";
			KalendarData = getCalendar("month", arguments.StartPeriod, arguments.EndPeriod, 1, arguments.CategoryID);
		</cfscript>
		
		<cfxml variable="rssFeed"><cfprocessingdirective suppresswhitespace="yes"><rss version="2.0">
	<channel>
		<title>Kalendar of Events for <cfoutput>#DateFormat(arguments.LinkDate, "mmmm yyyy")#</cfoutput></title>
		<link>http://<cfoutput>#cgi.SERVER_NAME##cgi.SCRIPT_NAME#</cfoutput></link>
		<description>Latest Events</description>
		<language>en-us</language>
		<copyright>Copyright 2006 TJ Downes</copyright>
		<pubDate><cfoutput>#publishDate#</cfoutput></pubDate>
		<lastBuildDate><cfoutput>#publishDate#</cfoutput></lastBuildDate>
		<generator>Kalendar</generator>
		<docs>http://cfopen.org/docman/?group_id=102</docs>
		<managingEditor><cfoutput>#Trim(getConfig().getRSSEditor())#</cfoutput></managingEditor>
		<webMaster><cfoutput>#Trim(getConfig().getRSSWebmaster())#</cfoutput></webMaster>
		<cfloop index="i" from="1" to="#ArrayLen(KalendarData)#">
				<cfif Month(KalendarData[i].StartDate) eq Month(LinkDate)>
					<cfscript>
					  title = XMLFormat(KalendarData[i].Title);
					  if(Len(Trim(KalendarData[i].StartTime))) {
					  	eventdate = DateConvert("local2Utc", DateFormat(KalendarData[i].StartDate, "m/d/yyyy") & " " & TimeFormat( KalendarData[i].StartTime ) );
						} else {
						eventdate = DateConvert("local2Utc", KalendarData[i].StartDate);
						}
					  eventdate = DateFormat(eventdate, "ddd, dd mmm yyyy") & " " & TimeFormat(eventdate, "HH:mm:ss") & " GMT";
					  description = XMLFormat(KalendarData[i].Description);
					  category = XMLFormat(Trim(KalendarData[i].CategoryName));
					  eventid = KalendarData[i].EventID;
					</cfscript><cfoutput><item>
			<title>#title#</title>
			<description>#description#</description>
			<link>http://#cgi.SERVER_NAME#/#cgi.SCRIPT_NAME#</link>
			<category>#category#</category>
			<pubDate>#eventdate#</pubDate>
			<guid>http://#cgi.SERVER_NAME##Replace(cgi.SCRIPT_NAME, ListLast(cgi.SCRIPT_NAME, "/"), "eventDetails.cfm")#?eventid=#eventid#</guid>
		</item></cfoutput></cfif></cfloop>
	</channel>
</rss></cfprocessingdirective></cfxml>
		<cfreturn rssFeed />
				
	</cffunction>


	<cffunction name="queryRowToStruct" access="private" output="false" returntype="struct">
		<cfargument name="qry" type="query" required="true">
		
		<cfscript>
			/**
			 * Makes a row of a query into a structure.
			 * 
			 * @param query 	 The query to work with. 
			 * @param row 	 Row number to check. Defaults to row 1. 
			 * @return Returns a structure. 
			 * @author Nathan Dintenfass (nathan@changemedia.com) 
			 * @version 1, December 11, 2001 
			 */
			//by default, do this to the first row of the query
			var row = 1;
			//a var for looping
			var ii = 1;
			//the cols to loop over
			var cols = listToArray(qry.columnList);
			//the struct to return
			var stReturn = structnew();
			//if there is a second argument, use that for the row number
			if(arrayLen(arguments) GT 1)
				row = arguments[2];
			//loop over the cols and build the struct from the query row
			for(ii = 1; ii lte arraylen(cols); ii = ii + 1){
				stReturn[cols[ii]] = qry[cols[ii]][row];
			}		
			//return the struct
			return stReturn;
		</cfscript>
	</cffunction>
	
	<cffunction name="getConfig" access="private" output="false" returntype="any">
		<cfreturn variables.private.Config />
	</cffunction>
</cfcomponent>